package com.youtills.core.email;

import com.youtills.core.lang.CollectionUtil;
import com.youtills.core.lang.StringUtil;
import com.youtills.core.config.Configuration;
import com.youtills.core.config.IConfig;
import com.youtills.core.config.IConfigMulti;
import com.sun.mail.smtp.SMTPSendFailedException;
import com.sun.mail.smtp.SMTPTransport;

import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * Created by IntelliJ IDEA.
 * User: ravi
 * Date: 8/11/12
 * Time: 1:48 PM
 * To change this template use File | Settings | File Templates.
 */
class SmtpEmailSender implements IEmailSender {

    /** LOG */
//    private static final Logger LOG = Logger.getLogger(SmtpEmail.class);

    /** Command for SMTP! */
    private static final String COMMAND = "Command: ";

    /** Return Code */
    private static final String RET_CODE = "RetCode: ";

    /** Mail Response */
    private static final String RESPONSE = "Response: ";

    /** Log message for missing property */
    private static final String PROPERTY_MISSING = " property missing";

    public static final String SMTP_EMAIL_SENDER_CONFIG_KEY = "smtp.email.sender.";
    public static final String SMTP_EMAIL_SENDER_CONFIG_USER_NAME = SMTP_EMAIL_SENDER_CONFIG_KEY + "user.name";
    public static final String SMTP_EMAIL_SENDER_CONFIG_USER_PASSWORD = SMTP_EMAIL_SENDER_CONFIG_KEY + "user.password";
    public static final String SMTP_EMAIL_SENDER_CONFIG_SECURE_SMTP = SMTP_EMAIL_SENDER_CONFIG_KEY + "secure.smtp";

    private final String name;
    private final Properties properties = new Properties();
    private String userName;
    private String password;
    private String protocol = "smtp";

    SmtpEmailSender(String name) {
        this.name = name;
        loadProperties(name);
    }

    SmtpEmailSender(){
        this.name = "Default Provider";
        loadProperties("");
    }

    private void loadProperties(String key){
        String configPrefix =  key + SMTP_EMAIL_SENDER_CONFIG_KEY;
        IConfigMulti configMulti = Configuration.getPrefixSuffixConfig(configPrefix, null, null);
        List<IConfig> configs = configMulti.getConfigs();
        if(!CollectionUtil.isEmpty(configs)){
            for(IConfig config : configs){
                if(config.getKey().endsWith(SMTP_EMAIL_SENDER_CONFIG_USER_NAME)){
                    this.userName = config.getStringValue();
                }else if(config.getKey().endsWith(SMTP_EMAIL_SENDER_CONFIG_USER_PASSWORD)){
                    this.password = config.getStringValue();
                }else if(config.getKey().endsWith(SMTP_EMAIL_SENDER_CONFIG_SECURE_SMTP)){
                    boolean isSecure = StringUtil.getBoolean(config.getStringValue(), false);
                    if(isSecure){
                        this.protocol = "smtps";
                    }
                }else{
                    String _key =   config.getKey().replaceFirst(configPrefix, "");
                    String _value =  config.getStringValue();
                    if(_key != null && _value != null){
                        properties.put(_key, _value);
                    }
                }
            }
        }
    }

    /**
     * Gives you protocol.
     *
     * @return  protocol type
     */
    private static String getProtocol() {
//        Boolean ssl = Configuration.MAIL_SMTP_SSL.getBoolean();

//        if ((ssl != null) && ssl) {
//            return "smtps";
//        } else {
        return "smtp";
//        }
    }

    /**
     * Gives you mail host.
     *
     * @return  mail host name
     */
    private static String getSmtpHost() {

//        String host = Configuration.MAIL_SMTP_HOST.getString();

//        if (host == null) {
//            throw new ConfigurationMissingException(Configuration.MAIL_SMTP_HOST.getKey()
//                + PROPERTY_MISSING);
//        }

//        return host;
//        return "www.deposolutions.com";
        return "localhost";
    }

    /**
     * Gives you user name.
     *
     * @return  user
     */
    private static String getSmtpUser(){
//        String user = Configuration.MAIL_SMTP_USER.getString();

//        if (user == null) {
//            throw new ConfigurationMissingException(Configuration.MAIL_SMTP_USER.getKey()
//                + PROPERTY_MISSING);
//        }

//        return user;
        return null;
    }

    /**
     * Gives you user name.
     *
     * @return  user
     */
    private static String getSmtpPassword() {
//        String password = Configuration.MAIL_SMTP_PASSWORD.getString();

//        if (password == null) {
//            throw new ConfigurationMissingException(Configuration.MAIL_SMTP_PASSWORD.getKey()
//                + PROPERTY_MISSING);
//        }

//        return password;
        return null;
    }



    public void send(IEmailMessage message)
            throws EmailException{

//        Properties props = System.getProperties();

        // Get a Session object

        Authenticator authenticator = null;
        if(!StringUtil.isEmpty(userName) || !StringUtil.isEmpty(password)){
            authenticator = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(userName, password);
                }
            };
        }

        Session session = Session.getInstance(this.properties, authenticator);

        // construct the message
        try {
            Message msg = new MimeMessage(session);

            if (message.getFromArray().length > 0) {
                msg.addFrom(message.getFromArray());
            } else {
                msg.setFrom();
            }

            msg.setRecipients(Message.RecipientType.TO, message.getToArray());

            if (message.getCcArray().length > 0) {
                msg.setRecipients(
                        Message.RecipientType.CC, message.getCcArray());
            }

            if (message.getBccArray().length > 0) {
                msg.setRecipients(
                        Message.RecipientType.BCC, message.getBccArray());
            }

            msg.setReplyTo(message.getReplyToArray());

            msg.setSubject(message.getSubject());

            String text = message.getBody();

            MimeMultipart mp = new MimeMultipart();

            MimeBodyPart mbp = new MimeBodyPart();

            if (message.isHtml()) {
                try {
                    mbp.setDataHandler(new DataHandler(
                            new ByteArrayDataSource(text, "text/html")));
                } catch (IOException e) {
                    throw new EmailException("io exception",e);
                }
            } else {
                mbp.setText(text);
            }

            mp.addBodyPart(mbp);

            for (File attachment : message.getAttachments()) {
                mbp = new MimeBodyPart();
                try {
                    mbp.attachFile(attachment);
                } catch (IOException e) {
                    throw new EmailException("io exception",e);
                }
                mp.addBodyPart(mbp);
            }

            msg.setContent(mp);

            // Setting current date
            msg.setSentDate(new Date());


            SMTPTransport transport = (SMTPTransport) session.getTransport(this.protocol);

            try {

//                if(!StringUtil.isEmpty(userName) || !StringUtil.isEmpty(password)){
//                    transport.connect(getSmtpHost(), getSmtpUser(), getSmtpPassword());
//                } else {
                transport.connect();
//                }

                transport.sendMessage(msg, msg.getAllRecipients());
            } catch (SMTPSendFailedException sfe) {
//                LOG.error(
//                    MessageFormat.format(
//                        "SMTP SEND FAILED:{0}{1} {2}{3} {4}{5}",
//                        COMMAND, sfe.getCommand(), RET_CODE,
//                        sfe.getReturnCode(), RESPONSE,
//                        sfe.getMessage()));

                throw sfe;
            } finally {
                transport.close();
            }

        } catch (MessagingException e) {
            throw new EmailException(e, "Problems setting up email: " + e.toString());
        }

//        LOG.debug("Mail was sent successfully.");
    }

}